#include "mainwindowcontroller.h"

#include <QSettings>

#include "ui/mainwindow.h"
#include "chanlist.h"
#include "log.h"
#include "components/board.h"

namespace Wishmaster
{
	MainWindowController::MainWindowController(ChanManager* manager, MainWindow *parent) :
		QObject(parent), m_chanManager(manager), m_window(parent),
		m_activeChanIndex(-1),
		m_activeBoardIndex(-1)
	{
	}

	void MainWindowController::setActiveChanIndex(int index)
	{
		ChanList* list = m_chanManager->chanlist();
		Q_ASSERT(list);

		if((index < 0) || (index >= list->chansCount()))
		{
			log(llError, "MainWindowController::setActiveChanIndex: invalid index %d requested", index);
			return;
		}

		m_activeChanIndex = index;
		m_activeBoardIndex = -1;

		QStringList boardsaliases = list->getChan(index)->getBoardAliases();
		QStringList res;
		foreach(QString s, boardsaliases)
		{
			res.append(s);
		}
		emit boardListChanged(res);
	}

	int MainWindowController::activeChanIndex() const
	{
		return m_activeChanIndex;
	}

	Chan* MainWindowController::activeChan() const
	{
		ChanList* list = m_chanManager->chanlist();
		Q_ASSERT(list);

		return list->getChan(m_activeChanIndex);
	}

	void MainWindowController::setActiveBoardIndex(int index)
	{
		log(llDebug, "MainWindowController::setActiveBoard: %d/%d", index, m_activeBoardIndex);
		if(m_activeBoardIndex == index)
			return;

		ChanList* list = m_chanManager->chanlist();
		Q_ASSERT(list);

		Chan* chan = list->getChan(activeChanIndex());
		if(!chan)
			return;

		if((index < 0) || (index >= chan->boardsCount()))
		{
			log(llError, "MainWindowController::setActiveBoardIndex: invalid index %d requested", index);
			return;
		}

		m_activeBoardIndex = index;

		Board* b = chan->board(index);

		if(shouldBeRefreshed(b))
			m_chanManager->requestBoardIndex(chan->name(), b->name());

		emit threadListChanged();
	}

	int MainWindowController::activeBoardIndex() const
	{
		return m_activeBoardIndex;
	}

	Board* MainWindowController::activeBoard() const
	{
		Chan* chan = activeChan();
		if(!chan)
			return 0;
		return chan->board(m_activeBoardIndex);
	}

	void MainWindowController::setActiveThreadId(const ThreadId& threadId)
	{
		log(llDebug, "MainWindowController::setActiveThreadId");

		ChanList* list = m_chanManager->chanlist();
		Q_ASSERT(list);

		Chan* chan = list->getChan(threadId.chanName());
		if(!chan)
		{
			log(llError, "MainWindowController::setActiveThreadId: unable to find chan");
			return;
		}

		Board* b = chan->board(threadId.boardId());
		if(!b)
		{
			log(llError, "MainWindowController::setActiveThreadId: unable to find board");
			return;
		}

		ThreadPtr thread = b->getThread(threadId);
		if(!thread)
		{
			log(llError, "MainWindowController::setActiveThreadId: unable to find thread");
			return;
		}

		m_activeThreadId = threadId;

		emit threadActivated(threadId);

		thread->unswap();
		if(thread->flag(Thread::Alive))
		{
			bool success = m_chanManager->requestThread(threadId);
			if(!success)
			{
				log(llDebug, "unable to request thread: %d", threadId.threadNumericId());
			}
		}
	}

	ThreadId MainWindowController::activeThreadId() const
	{
		return m_activeThreadId;
	}

	// Has dependency on QSettings and QTimeDate
	// Should be overriden in tests
	bool MainWindowController::shouldBeRefreshed(Board* b)
	{
		QSettings settings;
		return (settings.value("autorefresh/lazy").toBool() &&
		   b->refreshTime().secsTo(QDateTime::currentDateTime()) > 20); // FIXME hardcoded const
	}
}
